package top.milkbox.utils;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * 生成验证码的工具类
 *
 * 如何使用：
 * 在servlet中复制一下代码
 */

/**
 *  try {
 *      int width = 160;
 *      int height = 55;
 *      //生成对应宽高的初始图片
 *      BufferedImage verifyImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
 *      // 将对应的图片传入，并传入宽高。在图片中添加字符和噪点，返回添加的字符
 *      String randomText = GuoUtilsVerifyCode.drawRandomText(width, height, verifyImg);
 *      // 打印验证码
 *      System.out.println(randomText);
 *      // 将验证码存入session域对象中
 *      HttpSession session = request.getSession();
 *      session.setAttribute("verification", randomText);
 *      // 必须设置响应内容类型为图片，否则前台不识别
 *      response.setContentType("image/png");
 *      // 获取文件输出流
 *      OutputStream outputStream = response.getOutputStream();
 *      // 输出图片流
 *      ImageIO.write(verifyImg, "png", outputStream);
 *  } catch (IOException e) {
 *      e.printStackTrace();
 *  }
 */

/**
 * // 验证码校验
 * String check = request.getParameter("check");
 * HttpSession session = request.getSession();
 * String verification = (String) session.getAttribute("verification");
 * if (check == null || !check.equalsIgnoreCase(verification)) {
 *     // 验证码错误
 *     ResultInfo resultInfo = new ResultInfo(false, null, "验证码错误");
 *     // 转为json
 *     ObjectMapper objectMapper = new ObjectMapper();
 *     String json = objectMapper.writeValueAsString(resultInfo);
 *
 *     // 响应
 *     System.out.println("验证码错误" + json);
 *     response.getWriter().write(json);
 *     return;
 * }
 * // 及时销毁验证码
 * session.removeAttribute("verification");
 */

/**
 * @version 2021年9月28日
 */
public class GuoUtilsVerifyCode {

    /**
     * 创建指定大小的图片，并添加4个字符和一些噪点
     * 此方法来自互联网
     *
     * @param width     图片宽度
     * @param height    图片高度
     * @param verifyImg 图片输入流
     * @return 返回随机生成的4字符组成的字符串，用于校验
     */
    public static String drawRandomText(int width, int height, BufferedImage verifyImg) {
        Graphics2D graphics = (Graphics2D) verifyImg.getGraphics();
        graphics.setColor(Color.WHITE);//设置画笔颜色-验证码背景色
        graphics.fillRect(0, 0, width, height);//填充背景
        graphics.setFont(new Font("微软雅黑", Font.BOLD, 40));
        //数字和字母的组合
        String baseNumLetter = "23456789abcdefghkmnpqrstwxyzABCEFGHKPRSTWXYZ";

        StringBuffer sBuffer = new StringBuffer();
        int x = 10;  //旋转原点的 x 坐标
        String ch = "";
        Random random = new Random();
        for (int i = 0; i < 4; i++) {
            graphics.setColor(getRandomColor());
            //设置字体旋转角度
            int degree = random.nextInt() % 30;  //角度小于30度
            int dot = random.nextInt(baseNumLetter.length());
            ch = baseNumLetter.charAt(dot) + "";
            sBuffer.append(ch);
            //正向旋转
            graphics.rotate(degree * Math.PI / 180, x, 45);
            graphics.drawString(ch, x, 45);
            //反向旋转
            graphics.rotate(-degree * Math.PI / 180, x, 45);
            x += 30;
        }
        //画干扰线
        for (int i = 0; i < 6; i++) {
            // 设置随机颜色
            graphics.setColor(getRandomColor());
            // 随机画线
            graphics.drawLine(random.nextInt(width), random.nextInt(height),
                    random.nextInt(width), random.nextInt(height));
        }
        //添加噪点
        for (int i = 0; i < 30; i++) {
            int x1 = random.nextInt(width);
            int y1 = random.nextInt(height);
            graphics.setColor(getRandomColor());
            graphics.fillRect(x1, y1, 2, 2);
        }
        return sBuffer.toString();
    }

    /**
     * 随机取色
     * 此方法来自互联网
     *
     * @return 返回一个Color对象
     */
    private static Color getRandomColor() {
        Random ran = new Random();
        Color color = new Color(ran.nextInt(256),
                ran.nextInt(256), ran.nextInt(256));
        return color;
    }
}
